home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / redakcyjne / programy / VideoLAN Client (VLC) 1.0.5 / vlc-1.0.5-win32.exe / lua / intf / telnet.lua < prev   
Text File  |  2010-01-30  |  8KB  |  223 lines

  1. --[==========================================================================[
  2.  telnet.lua: VLM interface plugin
  3. --[==========================================================================[
  4.  Copyright (C) 2007 the VideoLAN team
  5.  $Id$
  6.  
  7.  Authors: Antoine Cellerier <dionoea at videolan dot org>
  8.  
  9.  This program is free software; you can redistribute it and/or modify
  10.  it under the terms of the GNU General Public License as published by
  11.  the Free Software Foundation; either version 2 of the License, or
  12.  (at your option) any later version.
  13.  
  14.  This program is distributed in the hope that it will be useful,
  15.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  GNU General Public License for more details.
  18.  
  19.  You should have received a copy of the GNU General Public License
  20.  along with this program; if not, write to the Free Software
  21.  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22. --]==========================================================================]
  23.  
  24. description=
  25. [============================================================================[
  26.  VLM Interface plugin
  27.  
  28.  Copy (features wise) of the original VLC modules/control/telnet.c module.
  29.  
  30.  Differences are:
  31.     * it's in Lua
  32.     * 'lock' command to lock the telnet promt
  33.     * possibility to listen on different hosts including stdin
  34.       for example:
  35.         listen on stdin: vlc -I lua --lua-intf telnet --lua-config "telnet={host='*console'}"
  36.         listen on stdin + 2 ports on localhost: vlc -I lua --lua-intf telnet --lua-config "telnet={hosts={'localhost:4212','localhost:5678','*console'}}"
  37.  
  38.  Configuration options setable throught the --lua-config option are:
  39.     * hosts: A list of hosts to listen on (see examples above).
  40.     * host: A host to listen on. (won't be used if `hosts' is set)
  41.     * password: The password used for remote clients.
  42.     * prompt: The prompt.
  43. ]============================================================================]
  44.  
  45. require "host"
  46.  
  47. --[[ Some telnet command special characters ]]
  48. WILL = "\251" -- Indicates the desire to begin performing, or confirmation that you are now performing, the indicated option.
  49. WONT = "\252" -- Indicates the refusal to perform, or continue performing, the indicated option.
  50. DO   = "\253" -- Indicates the request that the other party perform, or confirmation that you are expecting the other party to perform, the indicated option.
  51. DONT = "\254" -- Indicates the demand that the other party stop performing, or confirmation that you are no longer expecting the other party to perform, the indicated option.
  52. IAC  = "\255" -- Interpret as command
  53.  
  54. ECHO = "\001"
  55.  
  56. --[[ Client status change callbacks ]]
  57. function on_password( client )
  58.     if client.type == host.client_type.net then
  59.         client:send( "Password: " ..IAC..WILL..ECHO )
  60.     else
  61.         -- no authentification needed on stdin
  62.         client:switch_status( host.status.read )
  63.     end
  64. end
  65. function on_read( client )
  66.     client:send( config.prompt and tostring(config.prompt) or "> " )
  67. end
  68. function on_write( client )
  69. end
  70.  
  71. --[[ Misc functions ]]
  72. function telnet_commands( client )
  73.     -- remove telnet command replies from the client's data
  74.     client.buffer = string.gsub( client.buffer, IAC.."["..DO..DONT..WILL..WONT.."].", "" )
  75. end
  76.  
  77. function vlm_message_to_string(client,message,prefix)
  78.     local prefix = prefix or ""
  79.     if message.value then
  80.         client:append(prefix .. message.name .. " : " .. message.value)
  81.         return
  82.     else
  83.         client:append(prefix .. message.name)
  84.         if message.children then
  85.             for i,c in ipairs(message.children) do
  86.                 vlm_message_to_string(client,c,prefix.."    ")
  87.             end
  88.         end
  89.         return
  90.     end
  91. end
  92.  
  93. --[[ Configure the host┬á]]
  94. h = host.host()
  95.  
  96. h.status_callbacks[host.status.password] = on_password
  97. h.status_callbacks[host.status.read] = on_read
  98. h.status_callbacks[host.status.write] = on_write
  99.  
  100. h:listen( config.hosts or config.host or "localhost:4212" )
  101. password = config.password or "admin"
  102.  
  103. --[[┬áLaunch vlm ]]
  104. vlm = vlc.vlm()
  105.  
  106. --[[ Commands ]]
  107. function shutdown(client)
  108.     h:broadcast("Shutting down.\r\n")
  109.     vlc.msg.err("shutdown requested")
  110.     vlc.misc.quit()
  111.     return true
  112. end
  113. function logout(client)
  114.     client:del()
  115.     return true
  116. end
  117. function quit(client)
  118.     if client.type == host.client_type.net then
  119.         return logout(client)
  120.     else
  121.         return shutdown(client)
  122.     end
  123. end
  124. function lock(client)
  125.     client:send("\r\n")
  126.     client:switch_status( host.status.password )
  127.     client.buffer = ""
  128.     return false
  129. end
  130. function print_text(text)
  131.     return function(client)
  132.         client:append(string.gsub(text,"\r?\n","\r\n"))
  133.         return true
  134.     end
  135. end
  136. function help(client)
  137.     client:append("    Telnet Specific Commands:")
  138.     for c,t in pairs(commands) do
  139.         client:append("        "..c.." : "..t.help)
  140.     end
  141.     return true
  142. end
  143. commands = {
  144.     ["shutdown"]    = { func = shutdown, help = "shutdown VLC" },
  145.     ["quit"]        = { func = quit, help = "logout from telnet/shutdown VLC from local shell" },
  146.     ["logout"]      = { func = logout, help = "logout" },
  147.     ["lock"]        = { func = lock, help = "lock the telnet prompt" },
  148.     ["description"] = { func = print_text(description), help = "describe this module" },
  149.     ["license"]     = { func = print_text(vlc.misc.license()), help = "print VLC's license message" },
  150.     ["help"]        = { func = help, help = "show this help", dovlm = true },
  151.     }
  152.  
  153. function client_command( client )
  154.     local cmd = client.buffer
  155.     client.buffer = ""
  156.     if not commands[cmd] or not commands[cmd].func or commands[cmd].dovlm then
  157.         -- if it's not an interface specific command, it has to be a VLM command
  158.         local message, vlc_err = vlm:execute_command( cmd )
  159.         vlm_message_to_string( client, message )
  160.         if not commands[cmd] or not commands[cmd].func and not commands[cmd].dovlm then
  161.             if vlc_err ~= 0 then client:append( "Type `help' for help." ) end
  162.             return true
  163.         end
  164.     end
  165.     ok, msg = pcall( commands[cmd].func, client )
  166.     if not ok then
  167.         client:append( "Error in `"..cmd.."' "..msg )
  168.         return true
  169.     end
  170.     return msg
  171. end
  172.  
  173. --[[ The main loop ]]
  174. while not vlc.misc.should_die() do
  175.     h:accept()
  176.     local w, r = h:select( 0.1 )
  177.  
  178.     -- Handle writes
  179.     for _, client in pairs(w) do
  180.         local len = client:send()
  181.         client.buffer = string.sub(client.buffer,len+1)
  182.         if client.buffer == "" then client:switch_status( host.status.read ) end
  183.     end
  184.  
  185.     -- Handle reads
  186.     for _, client in pairs(r) do
  187.         local str = client:recv(1000)
  188.         local done = false
  189.         if string.match(str,"\n$") then
  190.             client.buffer = string.gsub(client.buffer..str,"\r?\n$","")
  191.             done = true
  192.         elseif client.buffer == ""
  193.            and ((client.type == host.client_type.stdio and str == "")
  194.            or  (client.type == host.client_type.net and str == "\004")) then
  195.             -- Caught a ^D
  196.             client.buffer = "quit"
  197.             done = true
  198.         else
  199.             client.buffer = client.buffer .. str
  200.         end
  201.         if client.type == host.client_type.net then
  202.             telnet_commands( client )
  203.         end
  204.         if done then
  205.             if client.status == host.status.password then
  206.                 if client.buffer == password then
  207.                     client:send( IAC..WONT..ECHO.."\r\nWelcome, Master\r\n" )
  208.                     client.buffer = ""
  209.                     client:switch_status( host.status.write )
  210.                 else
  211.                     client:send( "\r\nWrong password\r\nPassword: " )
  212.                     client.buffer = ""
  213.                 end
  214.             elseif client_command( client ) then
  215.                 client:switch_status( host.status.write )
  216.             end
  217.         end
  218.     end
  219. end
  220.  
  221. --[[ Clean up ]]
  222. vlm = nil
  223.